package git.soulbgm.websocket;

import git.soulbgm.utils.JsonTool;
import git.soulbgm.utils.LogHelper;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 推送告警数量
 *
 * @author SoulBGM
 * @date 2021-08-24
 */
@ServerEndpoint("/alarm/count/{username}")
@Component
public class AlarmWebSocketServer {

    private static final LogHelper LOG = new LogHelper(AlarmWebSocketServer.class);
    private static final AtomicInteger ONLINE_NUM = new AtomicInteger();
    private static final ConcurrentHashMap<String, Session> SESSION_POOLS = new ConcurrentHashMap<>();

    /**
     * 发送消息
     *
     * @param session 会话
     * @param message 消息
     * @throws IOException IO异常
     */
    public static synchronized void sendMessage(Session session, String message) throws IOException {
        if (session != null) {
            session.getBasicRemote().sendText(message);
        }
    }

    /**
     * 给指定用户发送信息
     *
     * @param username 用户名
     * @param message  消息
     */
    public static void sendInfo(String username, String message) {
        Session session = SESSION_POOLS.get(username);
        try {
            sendMessage(session, message);
        } catch (Exception e) {
            LOG.error("给 {} 用户发送数据出现异常", username, e);
        }
    }

    /**
     * 给指定用户发送信息
     *
     * @param username 用户名
     * @param obj      消息对象
     */
    public static void sendInfo(String username, Object obj) {
        sendInfo(username, JsonTool.toJson(obj));
    }

    /**
     * 群发消息
     *
     * @param message 消息
     */
    public static void broadcast(String message) {
        Collection<Session> sessions = SESSION_POOLS.values();
        for (Session session : sessions) {
            try {
                sendMessage(session, message);
            } catch (Exception e) {
                LOG.error("群发消息出现异常", e);
            }
        }
    }

    /**
     * 群发消息
     *
     * @param obj 消息对象
     */
    public static void broadcast(Object obj) {
        broadcast(JsonTool.toJson(obj));
    }

    @OnOpen
    public void onOpen(Session session, @PathParam("username") String username) {
        SESSION_POOLS.put(username, session);
        addOnlineCount();
    }

    @OnClose
    public void onClose(@PathParam("username") String username) {
        SESSION_POOLS.remove(username);
        cutOnlineCount();
    }

    @OnMessage
    public void onMessage(@PathParam("username") String username, String message) {
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        LOG.error("会话IP {} ,出现异常", session.getRequestURI().getHost(), throwable);
    }

    /**
     * 添加在线计数
     */
    public static void addOnlineCount() {
        ONLINE_NUM.incrementAndGet();
    }

    /**
     * 减少在线计数
     */
    private static void cutOnlineCount() {
        ONLINE_NUM.decrementAndGet();
    }

    /**
     * 获得在线数量
     *
     * @return {@link AtomicInteger}
     */
    public static AtomicInteger getOnlineNum() {
        return ONLINE_NUM;
    }

    /**
     * 获得会话池
     *
     * @return {@link ConcurrentHashMap}<{@link String}, {@link Session}>
     */
    public static ConcurrentHashMap<String, Session> getSessionPools() {
        return SESSION_POOLS;
    }

}
